package test.guava;

import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import concurrent.ConcurrentUtil;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;

/**
 * 对多线程执行成功、失败回调和返回结果搜集的样例
 * @author shadowedge
 */
public class GuavaConcurrentResults {

	private static final Logger logger = LoggerFactory.getLogger(GuavaConcurrentResults.class);

	static ListeningExecutorService service = ConcurrentUtil.instance.getService(10,false);

	ListenableFuture future1, future2;
	static int i = 0;
//    transient  static int i = 0;
	public void exam() throws ExecutionException, InterruptedException {
			future1 = service.submit(() -> {
				logger.info("call future 1 , i = {}",i);
				return i++;
			});

			future2 = service.submit(() -> {
				logger.info("call future 2, i = {}",i);
				//       throw new RuntimeException("----call future 2.");
				return i++;
			});
		logger.info("当前工作线程组执行结果:{}",ConcurrentUtil.fetchResults(service,future1,future2));
	}

	@Test
	public void testFetchSingleResult() throws ExecutionException, InterruptedException {
		int size = 10;
	    for (int i = 0; i < size; i++) {
			exam();
		}
		//结果函数放在完成后运行，为取得最后一组线程执行结果
		logger.info("最后一组线程执行结果:{}",(Integer) ConcurrentUtil.fetchResults(service,future1));

	}

	@Test
	public void testFetchResults() throws ExecutionException, InterruptedException {
		int size = 10;
	    for (int i = 0; i < size; i++) {
	    	Thread.sleep(1000);
			exam();
		}
		//结果函数放在完成后运行，为取得最后一组线程执行结果
		logger.info("最后一组线程执行结果:{}",ConcurrentUtil.fetchResults(service,future1,future2));
		logger.info("i = {} , 我在最后执行，说明线程结果搜集正确！",i);
		Assert.assertEquals(2*size,i);
		ConcurrentLinkedQueue concurrentLinkedQueue;
	}
}
